import {Ajax} from "../ajax";
import {BaseDataModel} from "./base";
import common from "../common";


/**
 * 数据实体基类 action模式
 */
class ActionDataModel extends BaseDataModel {

  constructor() {
    super();

    this.$api = '';                  // 接口地址
    this.$getPageAction = '';           // 分页读取数据 Action
    this.$getAllAction = '';           //读取所有数据 Action
    this.$getAction = '';             // get单条数据 Action
    this.$setAction = '';             // 保存（添加、修改）数据 Action
    this.$delAction = '';           // 删除数据 Action
    this.$setMode = 'post';     // 调用set接口时的模式，可选值post、postJson、get，需要跟后台对应起来
    this.$delMode = 'post';     // 调用delete接口时的模式，可选值post、postJson、get，需要跟后台对应起来
  }


  $checkAction(actionName) {

    if (!this.$api) {
      throw new Error(`${this.constructor.name}未定义接口地址`);
    }
    if (!this[actionName]) {
      throw new Error(`${this.constructor.name}未定义${actionName}`);
    }
  }

  /**
   * 获取所有数据
   * @param {object} opt - 可选，传递给接口的查询参数
   * @returns {Promise<T>}
   */
  $getAll(opt) {
    this.$checkAction('$getAllAction');
    const data = {
      action: this.$getAllAction
    };
    if (opt && typeof opt === 'object') {
      Object.assign(data, opt);
    }
    return Ajax.post(this.$api, data).then(result => {
      const data = result.data || [];
      this.$afterGetList(data);
      this.$dataList = data;
      return data;
    });
  }

  /**
   * 获取分页数据
   * @param opt
   * @returns {Promise<T>}
   */
  $getPage(opt) {
    this.$checkAction('$getPageAction');
    const data = {
      action: this.$getPageAction,
      limit: this.$limit,
      offset: this.$limit * (this.$nowPage - 1)
    };
    Object.assign(data, this.$searchPara);
    Object.assign(data, opt || {});
    return Ajax.post(this.$api, data).then(result => {
      this.$totalPage = Math.ceil(result.total / this.$limit);
      this.$total = result.total;
      this.$afterGetList(result.data);
      this.$dataList = result.data;
      return result.data;
    });
  }

  /**
   * 根据id获取单条记录
   * @param {number} id - 标识 可不传递
   * @returns {Promise<T>}
   */
  $get(id) {
    this.$checkAction('$getAction');
    id = id || this.id;
    if (!id) {
      throw new Error('未传入有效ID');
    }
    return Ajax.post(this.$api, {
      action: this.$getAction,
      [this.$idField]: id
    }).then(result => {
      let data;
      if (Array.isArray(result.data)) {
        data = result.data[0];
      } else {
        data = result.data;
      }
      Object.assign(this, data);
      if (this.$idField !== 'id') {
        this.id = parseInt(data[this.$idField]);
      }
      this.$afterGet();
      return this;
    });
  }

  /**
   * 保存数据
   * @param {number} otherData -提交到后台的其他数据
   * @returns {*|Promise<AxiosResponse<any>>}
   */
  $save(otherData) {
    this.$checkAction('$setAction');

    return Ajax[this.$setMode](this.$api, Object.assign(common.assign({
      action: this.$setAction
    }, this, this.$keys), otherData));
  }

  /**
   * 删除数据
   * @returns {*|Promise<AxiosResponse<any>>}
   */
  $remove(id) {
    this.$checkAction('$delAction');
    return Ajax[this.$delMode](this.$api, {
      action: this.$delAction,
      [this.$idField]: id || this.id
    });
  }

  /**
   * 批量删除数据
   * @returns {*|Promise<AxiosResponse<any>>}
   */
  $removeBatch(ids) {
    this.$checkAction('$delAction');
    return Ajax[this.$delMode](this.$api, {
      action: this.$delAction,
      ids
    });
  }

}

export default ActionDataModel;

export {
  ActionDataModel
}
